home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / BSP Tree 1.2 / Sources / Graphics / source / polygon_3d.cp < prev    next >
Encoding:
Text File  |  1995-11-17  |  9.1 KB  |  138 lines  |  [TEXT/MMCC]

  1. //------------------------------------------------------------------------------
  2. //    File:                    polygon.cp
  3. //    Date:                    8/29/94
  4. //    Author:                Bretton Wade
  5. //
  6. //    Description:    this file contains the methods for a polygon
  7. //
  8. //------------------------------------------------------------------------------
  9.  
  10. #include "polygon_3d.h"
  11.  
  12. //------------------------------------------------------------------------------
  13. //    constructor
  14. //------------------------------------------------------------------------------
  15. polygon::polygon (point_3d *buffer, uchar cnt, va_list pts)                                            //    normal constructor
  16. {                                                                                                                                                                //    begin
  17.     count = cnt;                                                                                                                                    //    copy the point_3d count
  18.     points = new point_3d[count];                                                                                                    //    allocate the array of points
  19.     for (short i = 0; i < count; i++)                                                                                            //    loop for every point_3d
  20.         points[i] = buffer[va_arg(pts, int)];                                                                                //    copying it into the points array of the polygon
  21.     plane.Define (Normal (), points[0]);                                                                                    //    compute the plane_3d equation
  22. }                                                                                                                                                                //    end
  23.  
  24. //------------------------------------------------------------------------------
  25. //    constructor
  26. //------------------------------------------------------------------------------
  27. polygon::polygon (point_3d *buffer, uchar cnt)                                                                    //    normal constructor
  28. {                                                                                                                                                                //    begin
  29.     count = cnt;                                                                                                                                    //    copy the point_3d count
  30.     points = new point_3d[count];                                                                                                    //    allocate the array of points
  31.     for (short i = 0; i < count; i++)                                                                                            //    loop for every point_3d
  32.         points[i] = buffer[i];                                                                                                            //    copying it into the points array of the polygon
  33.     plane.Define (Normal (), points[0]);                                                                                    //    compute the plane_3d equation
  34. }                                                                                                                                                                //    end
  35.  
  36. //------------------------------------------------------------------------------
  37. //    destructor
  38. //------------------------------------------------------------------------------
  39. polygon::~polygon (void)                                                                                                                //    destructor
  40. {                                                                                                                                                                //    begin
  41.     delete[] points;                                                                                                                            //    delete the point_3d array
  42. }                                                                                                                                                                //    end
  43.  
  44. //------------------------------------------------------------------------------
  45. //    compute the polygon normal
  46. //------------------------------------------------------------------------------
  47. vector_3d    polygon::Normal (void) const                                                                                    //    compute the plane_3d normal vector_3d using Newell's method
  48. {                                                                                                                                                                //    begin
  49.     //    assumes counter-clockwise point_3d order
  50.     vector_3d    sum (ZERO_VECTOR);                                                                                                    //    start with a zero vector_3d
  51.     for (short i = 0, last = count - 1; i < count; last = i, i++)                                    //    loop through all of the points
  52.     {                                                                                                                                                            //    begin
  53.         point_3d    A = points[last],                                                                                                    //    a point_3d
  54.                             B = points[i];                                                                                                        //    the following point_3d
  55.         sum[X] += (A[Y] - B[Y]) * (A[Z] + B[Z]);                                                                        //    add this edge's contribution to the average vector_3d
  56.         sum[Y] += (A[Z] - B[Z]) * (A[X] + B[X]);                                                                        //    add this edge's contribution to the average vector_3d
  57.         sum[Z] += (A[X] - B[X]) * (A[Y] + B[Y]);                                                                        //    add this edge's contribution to the average vector_3d
  58.     }                                                                                                                                                            //    end
  59.     return sum.Normalize ();                                                                                                            //    return the unit length normal vector_3d
  60. }                                                                                                                                                                //    end
  61.  
  62. //------------------------------------------------------------------------------
  63. //    check polygon for containment of a coplanar point_3d
  64. //------------------------------------------------------------------------------
  65. bool    polygon::Contains (const point_3d &pt) const                                                            //    test the point_3d to see if it is inside the polygon
  66. {                                                                                                                                                                //    begin
  67.     //    based on code by Eric Haines from Graphics Gems IV
  68.     coord    x, y;                                                                                                                                        //    indexing values
  69.     switch (plane.MajorAxis ())                                                                                                        //    switch on the major axis of the plane_3d
  70.     {                                                                                                                                                            //    begin
  71.         case X:    x = Y; y = Z; break;                                                                                                //    throw away the x coordinate
  72.         case Y:    x = Z; y = X; break;                                                                                                //    throw away the y coordinate
  73.         case Z:    x = X; y = Y; break;                                                                                                //    throw away the z coordinate
  74.     }                                                                                                                                                            //    end
  75.     real    tx = pt[x], ty = pt[y];                                                                                                    //    temporary values
  76.     point_3d    *p1 = &points[count - 1], *p2 = points;                                                            //    pointers to the points composing the edge being tested
  77.     int        yflag0 = ((*p1)[y] >= ty),                                                                                            //    check to see which side of the test point_3d the first point_3d is on
  78.                 inside = FALSE;                                                                                                                    //    start with inside false
  79.   for (int i = count; i--;)                                                                                                            //    loop over all of the points
  80.     {                                                                                                                                                            //    begin
  81.         int    yflag1 = ((*p2)[y] >= ty);                                                                                            //    check which side of the test point_3d the subsequent point_3d lies on
  82.         if (yflag0 != yflag1)                                                                                                                //    if the points aren't on the same side
  83.         {                                                                                                                                                        //    begin
  84.           int    xflag0 = ((*p1)[x] >= tx);                                                                                        //    check which side of the test coordinate the start point_3d is on
  85.         if (xflag0 == ((*p2)[x] >= tx))                                                                                        //    if the edge is all the way to one side of the test point_3d
  86.             {                                                                                                                                                    //    begin
  87.                 if (xflag0)                                                                                                                            //    if the start point_3d is greater than the test point_3d
  88.                     inside = !inside;                                                                                                            //    increment the crossing count
  89.             }                                                                                                                                                    //    end
  90.            else                                                                                                                                            //    otherwise, the edge spans the test point_3d on both axes
  91.             {                                                                                                                                                    //    begin
  92.                 if (((*p2)[x] - ((*p2)[y] - ty) * ((*p1)[x] - (*p2)[x]) / ((*p1)[y] - (*p2)[y])) >= tx)    //    if the intersection of the tx axis is on the right side of the test point_3d
  93.                 inside = !inside;                                                                                                            //    increment the crossing count
  94.             }                                                                                                                                                    //    end
  95.         }                                                                                                                                                        //    end
  96.         yflag0 = yflag1;                                                                                                                        //    save the point_3d classification
  97.         p1 = p2;                                                                                                                                        //    skip to the subsequent point_3d
  98.         p2 ++;                                                                                                                                            //    advance the subsequent point_3d
  99.    }                                                                                                                                                        //    end
  100.    return bool (inside);                                                                                                                //    return the result
  101.    return FALSE;
  102. }                                                                                                                                                                //    end
  103.  
  104. //------------------------------------------------------------------------------
  105. //    compute the area of the polygon
  106. //------------------------------------------------------------------------------
  107. real    polygon::Area (void) const                                                                                                //    compute the area of the polygon
  108. {                                                                                                                                                                //    begin
  109.     vector_3d    sum = ZERO_VECTOR;                                                                                                    //    start with a zero vector_3d
  110.     for (short i = 0, last = count - 1; i < count; last = i, i++)                                    //    loop on the points
  111.         sum += (vector_3d (points[last])) ^ (vector_3d (points[i]));                                //    take the cross product between two points
  112.     return R(0.5) * sum.Norm ();                                                                                                    //    return the length over 2
  113. }                                                                                                                                                                //    end
  114.  
  115. //------------------------------------------------------------------------------
  116. //    reverse the orientation of the polygon
  117. //------------------------------------------------------------------------------
  118. void    polygon::Invert (void)                                                                                                        //    completely reverse the orientation of the polygon
  119. {                                                                                                                                                                //    begin
  120.     point_3d    *pts = new point_3d[count];                                                                                    //    allocate a new block of points
  121.     short    reverse = count - 1;                                                                                                        //    presubtract the count to find the reverse addition value
  122.     for (short i = 0; i < count; i++)                                                                                            //    loop over all the points again
  123.         pts[i] = points[reverse - i];                                                                                                //    copying them in reverse order
  124.     delete[] points;                                                                                                                            //    delete the old points array
  125.     points = pts;                                                                                                                                    //    set the points array
  126.     plane.Invert ();                                                                                                                            //    reverse the plane_3d equation
  127. }                                                                                                                                                                //    end
  128.  
  129. //------------------------------------------------------------------------------
  130. //    compute the distance at which the ray intersects the polygon
  131. //------------------------------------------------------------------------------
  132. real        polygon::RayIntersection (const ray &r) const                                                        //    return the distance along the ray at which the intersection occurs
  133. {                                                                                                                                                                //    begin
  134.     return    plane.RayIntersection (r);                                                                                        //    return the distance along the ray to the plane_3d
  135. }                                                                                                                                                                //    end
  136.  
  137. //------------------------------------------------------------------------------
  138.